﻿using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Navigation;

namespace LeafBrowser.ViewModels
{
    public class BrowserTabViewModel : BindableBase
    {
        /// <summary>
        /// 浏览器对象
        /// </summary>
        public Microsoft.Web.WebView2.Wpf.WebView2 WebView { get; set; }


        private double zoomFactor = 1;
        /// <summary>
        /// 缩放比例
        /// </summary>
        public double ZoomFactor
        {
            get { return zoomFactor; }
            set { SetProperty(ref zoomFactor, value); }
        }



        private string address;
        public string Address
        {
            get { return address; }
            set { SetProperty(ref address, value); }
        }

        private string addressEditable;
        public string AddressEditable
        {
            get { return addressEditable; }
            set { SetProperty(ref addressEditable, value); }
        }

        private string outputMessage;
        public string OutputMessage
        {
            get { return outputMessage; }
            set { SetProperty(ref outputMessage, value); }
        }

        private string statusMessage;
        public string StatusMessage
        {
            get { return statusMessage; }
            set { SetProperty(ref statusMessage, value); }
        }

        private string title;
        public string Title
        {
            get { return title; }
            set { SetProperty(ref title, value); }
        }

        private double titleWidth;
        public double TitleWidth
        {
            get { return titleWidth; }
            set { SetProperty(ref titleWidth, value); }
        }


        private bool isNavigating = false;
        /// <summary>
        /// 正在加载
        /// </summary>
        public bool IsNavigating
        {
            get { return isNavigating; }
            set { SetProperty(ref isNavigating, value); }
        }

        private object evaluateJavaScriptResult;
        public object EvaluateJavaScriptResult
        {
            get { return evaluateJavaScriptResult; }
            set { SetProperty(ref evaluateJavaScriptResult, value); }
        }

        private bool showSidebar;
        public bool ShowSidebar
        {
            get { return showSidebar; }
            set { SetProperty(ref showSidebar, value); }
        }

        private bool showDownloadInfo;
        public bool ShowDownloadInfo
        {
            get { return showDownloadInfo; }
            set { SetProperty(ref showDownloadInfo, value); }
        }

        private string lastDownloadAction;
        public string LastDownloadAction
        {
            get { return lastDownloadAction; }
            set { SetProperty(ref lastDownloadAction, value); }
        }

        //private DownloadItem downloadItem;
        //public DownloadItem DownloadItem
        //{
        //    get { return downloadItem; }
        //    set { Set(ref downloadItem, value); }
        //}

        public DelegateCommand HomeCommand { get; set; }
        public DelegateCommand BrowseBackCommand { get; set; }
        public DelegateCommand BrowseForwardCommand { get; set; }
        public DelegateCommand BrowseStopCommand { get; set; }
        public DelegateCommand BrowseRefreshCommand { get; set; }
        public DelegateCommand GoToPageCommand { get; set; }
        public DelegateCommand IncreaseZoomCommand { get; set; }
        public DelegateCommand DecreaseZoomCommand { get; set; }
        public DelegateCommand RecoverZoomCommand { get; set; }


        public ICommand ExecuteJavaScriptCommand { get; private set; }
        public ICommand EvaluateJavaScriptCommand { get; private set; }
        public ICommand ShowDevToolsCommand { get; private set; }
        public ICommand CloseDevToolsCommand { get; private set; }
        public ICommand JavascriptBindingStressTest { get; private set; }

        //默认主页
        private string DefaultUrlForAddedTabs;
        public BrowserTabViewModel(string address)
        {
            DefaultUrlForAddedTabs = address;
            Address = address;
            AddressEditable = Address;
            Title = "新页面";

            HomeCommand = new DelegateCommand(() => {
                AddressEditable = Address = address;
                WebView.EnsureCoreWebView2Async();
                Address = AddressEditable;
                WebView.CoreWebView2.Navigate(AddressEditable);
            });
            GoToPageCommand = new DelegateCommand(() =>
            {
                AddressEditable = ConveToHttp(AddressEditable);
                WebView.EnsureCoreWebView2Async();
                Address = AddressEditable;
                WebView.CoreWebView2.Navigate(AddressEditable);
            });

            BrowseBackCommand = new DelegateCommand(() => WebView.GoBack());
            BrowseForwardCommand = new DelegateCommand(() => WebView.GoForward());

            BrowseStopCommand = new DelegateCommand(() => WebView.Stop(), () => { return IsNavigating; });
            BrowseRefreshCommand = new DelegateCommand(() => WebView.Reload(), () => { return !IsNavigating; });//webView != null && webView.CoreWebView2 != null; });

            IncreaseZoomCommand = new DelegateCommand(() => ZoomFactor += 0.1);
            DecreaseZoomCommand = new DelegateCommand(() => ZoomFactor -= 0.1);
            RecoverZoomCommand = new DelegateCommand(() => ZoomFactor = 1);


            //ExecuteJavaScriptCommand = new RelayCommand<string>(ExecuteJavaScript, s => !String.IsNullOrWhiteSpace(s));
            //EvaluateJavaScriptCommand = new RelayCommand<string>(EvaluateJavaScript, s => !String.IsNullOrWhiteSpace(s));
            //ShowDevToolsCommand = new RelayCommand(() => webBrowser.ShowDevTools());
            //CloseDevToolsCommand = new RelayCommand(() => webBrowser.CloseDevTools());
            //JavascriptBindingStressTest = new RelayCommand(() =>
            //{
            //    WebBrowser.Load(CefExample.BindingTestUrl);
            //    WebBrowser.LoadingStateChanged += (e, args) =>
            //    {
            //        if (args.IsLoading == false)
            //        {
            //            Task.Delay(10000).ContinueWith(t =>
            //            {
            //                if (WebBrowser != null)
            //                {
            //                    WebBrowser.Reload();
            //                }
            //            });
            //        }
            //    };
            //});

            //PropertyChanged += OnPropertyChanged;

            //var version = string.Format("Chromium: {0}, CEF: {1}, CefSharp: {2}", Cef.ChromiumVersion, Cef.CefVersion, Cef.CefSharpVersion);
            //OutputMessage = version;
        }

        /// <summary>
        /// 更新是否能使用的状态
        /// </summary>
        public void UpdateBrowseRaiseCanExecuteChanged()
        {
            BrowseBackCommand.RaiseCanExecuteChanged();
            BrowseForwardCommand.RaiseCanExecuteChanged();
            BrowseStopCommand.RaiseCanExecuteChanged();
            BrowseRefreshCommand.RaiseCanExecuteChanged();
        }

        private string ConveToHttp(string url)
        {
            if (url.StartsWith("http"))
            {
                return url;
            }
            else
            {
                return String.Format("http://{0}", url);
            }
        }

        //private async void EvaluateJavaScript(string s)
        //{
        //    try
        //    {
        //        var response = await webBrowser.EvaluateScriptAsync(s);
        //        if (response.Success && response.Result is IJavascriptCallback)
        //        {
        //            response = await ((IJavascriptCallback)response.Result).ExecuteAsync("This is a callback from EvaluateJavaScript");
        //        }

        //        EvaluateJavaScriptResult = response.Success ? (response.Result ?? "null") : response.Message;
        //    }
        //    catch (Exception e)
        //    {
        //        MessageBox.Show("Error while evaluating Javascript: " + e.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
        //    }
        //}

        //private void ExecuteJavaScript(string s)
        //{
        //    try
        //    {
        //        webBrowser.ExecuteScriptAsync(s);
        //    }
        //    catch (Exception e)
        //    {
        //        MessageBox.Show("Error while executing Javascript: " + e.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
        //    }
        //}

        //private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        //{
        //    switch (e.PropertyName)
        //    {
        //        case "Address":
        //            AddressEditable = Address;
        //            break;

        //        case "WebBrowser":
        //            if (WebBrowser != null)
        //            {
        //                WebBrowser.ConsoleMessage += OnWebBrowserConsoleMessage;
        //                WebBrowser.StatusMessage += OnWebBrowserStatusMessage;

        //                // TODO: This is a bit of a hack. It would be nicer/cleaner to give the webBrowser focus in the Go()
        //                // TODO: method, but it seems like "something" gets messed up (= doesn't work correctly) if we give it
        //                // TODO: focus "too early" in the loading process...
        //                WebBrowser.FrameLoadEnd += (s, args) =>
        //                {
        //                    //Sender is the ChromiumWebBrowser object 
        //                    var browser = s as ChromiumWebBrowser;
        //                    if (browser != null && !browser.IsDisposed)
        //                    {
        //                        browser.Dispatcher.BeginInvoke((Action)(() => browser.Focus()));
        //                    }
        //                };
        //            }

        //            break;
        //    }
        //}

        //private void OnWebBrowserConsoleMessage(object sender, ConsoleMessageEventArgs e)
        //{
        //    OutputMessage = e.Message;
        //}

        //private void OnWebBrowserStatusMessage(object sender, StatusMessageEventArgs e)
        //{
        //    StatusMessage = e.Value;
        //}
    }
}
